package com.pig4cloud.pig.djjk.service;

import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pig4cloud.pig.admin.api.util.ParamResolver;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.core.util.RedisUtils;
import com.pig4cloud.pig.djjk.config.DeviceConfig;
import com.pig4cloud.pig.djjk.domain.entity.XCCJZP;
import com.pig4cloud.pig.djjk.domain.po.FaceLibSearchResp;
import com.pig4cloud.pig.djjk.domain.po.PortraitRequest;
import com.pig4cloud.pig.djjk.entity.TrackAnalysisEntity;
import com.pig4cloud.pig.djjk.entity.TrackRecordEntity;
import com.pig4cloud.pig.djjk.mapper.TrackRecordMapper;
import com.pig4cloud.pig.djjk.mapper.XCCJZPMapper;
import com.pig4cloud.pig.djjk.service.immi.FaceApiService;
import com.pig4cloud.pig.djjk.service.wd.WdboxService;
import com.wd.ais.domain.dto.*;
import com.wd.ais.service.AisPortraitsServiceImpl;
import com.wd.ais.service.AisToolsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import java.util.stream.Collectors;

@Service
public class DispatchService {
    Logger log = Logger.getLogger(DispatchService.class.getName());
    @Resource
    private FaceApiService faceApiService;
    @Resource
    private WdboxService wdboxService;

    @Resource
	XCCJZPMapper xccjzpMapper;
    @Resource
	DeviceConfig deviceConfig;

	@Resource
	TrackRecordMapper trackRecordMapper;
	@Resource
	TrackAnalysisService trackAnalysisService;

	@Resource
	AisToolsService aisToolsService;
    private TimedCache<String,Long> timedCache = new TimedCache<>(1000*60*60*10);
    @Resource(name = "aisPortraitsService1")
    AisPortraitsServiceImpl portraitsService1;
    public void aisToFaceLibSearch(AisEventReceiver receiver){
		if(checkFaceLibDistinct(receiver)){
			save2DB(receiver);
			portraitsAdd(receiver);
		}

    }

	/**人脸去重
	 *
	 * @param receiver
	 */
	private boolean checkFaceLibDistinct(AisEventReceiver receiver) {
		Long capturedTime = receiver.getCapturedTime();
		Long distinctSeconds = ParamResolver.getLong("FACE_DISTINCT",60l);
		Long distinctThreshold = ParamResolver.getLong("FACE_DISTINCT_THRESHOLD",50L);
		DateTime timeStart = DateUtil.offsetMinute(DateUtil.date(capturedTime), Convert.toInt(0 - distinctSeconds));

		byte[] imageByte = portraitsService1.downloadImage(receiver.getPortraitImage().getUrl());
		String base64 = Base64.encode(imageByte);
		base64 = "data:image/jpg;base64," + base64;

		CaptureDataRequest captureDataRequest = new CaptureDataRequest();
		captureDataRequest.setCaptureTimeStart(timeStart.getTime());
		captureDataRequest.setCaptureTimeEnd(capturedTime);
		captureDataRequest.setDeviceIdentifierIds(CollUtil.toList(receiver.getDeviceInfo().getDevice().getIdentifierId()));
		captureDataRequest.setSearchImageBase64(base64);
		captureDataRequest.setScore(Convert.toDouble(distinctThreshold));
		CaptureDbSearchResponse captureDbSearchResponse = aisToolsService.captureDbSearch(captureDataRequest);
		List<RecordsItem> list = captureDbSearchResponse.getList();
		if(CollUtil.isNotEmpty(list)){
			List<RecordsItem> collect = list.stream().filter(item -> RedisUtils.hasKey("AIS_DISTINCT_"+item.getSerialNumber()) ).collect(Collectors.toList());
			if(CollUtil.isNotEmpty(collect)){
				log.info(StrUtil.format("ais push device {} is distinct,SerialNumber id is {}",receiver.getDeviceInfo().getDevice().getDeviceCode(),receiver.getSerialNumber()));
				return false;
			}else{
				log.info(StrUtil.format("ais push device {} is not distinct 1,SerialNumber id is {}",receiver.getDeviceInfo().getDevice().getDeviceCode(),receiver.getSerialNumber()));
				RedisUtils.set("AIS_DISTINCT_"+receiver.getSerialNumber(),"1",distinctSeconds, TimeUnit.SECONDS);
				return true;
			}
		}else{
			log.info(StrUtil.format("ais push device {} is not distinct 2,SerialNumber id is {}",receiver.getDeviceInfo().getDevice().getDeviceCode(),receiver.getSerialNumber()));
			RedisUtils.set("AIS_DISTINCT_"+receiver.getSerialNumber(),"1",distinctSeconds, TimeUnit.SECONDS);
			return true;
		}
	}

    private void save2DB(AisEventReceiver receiver) {
        if(receiver.getPortraitImage()!=null && receiver.getPortraitImage().getUrl()!=null){
			TrackAnalysisEntity trackAnalysis = new TrackAnalysisEntity();
            String url = receiver.getPortraitImage().getUrl();
            String deviceCode = receiver.getDeviceInfo().getDevice().getDeviceCode();
//            if(!deviceConfig.getDevices().containsKey(deviceCode)){
//                log.info(StrUtil.format("ais push device {} is not reg ,see file application.yml",deviceCode));
//            }
//            deviceCode="09057001311310266075";
            byte[] imageByte = portraitsService1.downloadImage(url);
            if(imageByte==null){
                System.out.println("人脸库搜索失败，下载图片失败");
                return;
            }
            String base64 = Base64.encode(imageByte);
            String rybh="";
            String scoreStr="0";
            FaceLibSearchResp faceLibSearchResp = faceApiService.faceLibSearch(base64);
            if(faceLibSearchResp==null){
                System.out.println("人脸库搜索失败，人脸识别失败3");
                rybh="";
                scoreStr="0";
            }
            else {
                rybh = faceLibSearchResp.getRybh();

                if (StrUtil.isEmpty(rybh)) {
                    log.info("人脸库搜索失败，人脸识别失败4");
                    rybh = "";
                    scoreStr = "0";
                }
                else {
                    Float score = faceLibSearchResp.getScore();
                    scoreStr = Convert.toStr(score);
                }
            }
            String urlBj = receiver.getPanoramicImage().getUrl();
            byte[] imageByteBj = portraitsService1.downloadImage(urlBj);
            XCCJZP xccjzp = new XCCJZP();
            xccjzp.setRYBH(rybh);
            xccjzp.setXSD(scoreStr);
            xccjzp.setSBBH(deviceCode);
            xccjzp.setCJSJ(DateUtil.format(new Date(),"yyyyMMddHHmmss"));
//            xccjzp.setRLZP(imageByte);
            xccjzp.setZPZP(imageByte);
            xccjzp.setBJZP(imageByteBj);
            xccjzpMapper.insert(xccjzp);
            xccjzpMapper.callDJJK();


			TrackRecordEntity trackRecordEntity = new TrackRecordEntity();
			trackRecordEntity.setDeviceCode(xccjzp.getSBBH());
			trackRecordEntity.setDataSource("ais");
			trackRecordEntity.setDataType(xccjzp.getCRLX());
			trackRecordEntity.setPersonCode(xccjzp.getRYBH());
			trackRecordEntity.setIsMatch(StrUtil.isNotBlank(xccjzp.getRYBH())?"1":"0");
			trackRecordEntity.setZpid(xccjzp.getZPID());
			trackRecordEntity.setDataType("4");
			trackRecordMapper.insert(trackRecordEntity);

			if(StrUtil.isNotBlank(rybh)){
				Long existPersons = trackRecordMapper.selectCount(new LambdaQueryWrapper<TrackRecordEntity>()
						.eq(TrackRecordEntity::getDeviceCode, deviceCode)
						.eq(TrackRecordEntity::getDataSource, "ais")
						.likeRight(TrackRecordEntity::getCreateBy,DateUtil.today())
						.eq(TrackRecordEntity::getPersonCode,rybh)
						.eq(TrackRecordEntity::getDataType, "4"));
				if(existPersons>0){
					trackAnalysis.setMatchPersonCount(0);
				}else{
					trackAnalysis.setMatchPersonCount(1);
				}
			}else {
				trackAnalysis.setMatchPersonCount(0);
			}

			trackAnalysis.setDeviceCode(deviceCode);
			trackAnalysis.setTrackCount(1);
			if(StrUtil.isNotEmpty(rybh)){
				trackAnalysis.setMatchCaount(1);
				trackAnalysis.setNoMatchCaount(0);
			}else{
				trackAnalysis.setMatchCaount(0);
				trackAnalysis.setNoMatchCaount(1);
			}
			trackAnalysisService.updateTrackAnalysis(trackAnalysis);
        }
    }

    public void portraitsAdd(AisEventReceiver receiver) {
        String url =receiver.getPortraitImage().getUrl();
        String deviceCode = receiver.getDeviceInfo().getDevice().getDeviceCode();
        byte[] imageByte = portraitsService1.downloadImage(url);
        String base64 = Base64.encode(imageByte);

        PortraitRequest portraitRequest = new PortraitRequest();
        String uuid = UUID.randomUUID().toString();
        portraitRequest.setName(uuid);
        portraitRequest.setIdNumber(uuid);
        portraitRequest.setPhotoBase64(base64);
        AisPortraitsAddResponse aisPortraitsAddResponse = getAisPortraitsAddResponse(portraitRequest);
        if(aisPortraitsAddResponse!=null){
            timedCache.put(uuid,System.currentTimeMillis());
        }else{
            log.info("人脸库添加失败，人脸识别失败1");
        }
    }

    private AisPortraitsAddResponse getAisPortraitsAddResponse(PortraitRequest portraitRequest) {
        AisPortraitsAddRequest aisPortraitsAddRequest = new AisPortraitsAddRequest()
                .setName(portraitRequest.getName())
                .setType(AisPortraitsAddRequest.portraitsType.visitor.getValue())
                .setIdentity(portraitRequest.getIdNumber())
                .setForced(0)
//                .setIdNumber(portraitRequest.getIdNumber())
                .setEnableState(1)
                .setActivationTime(DateUtil.beginOfDay(new Date()).getTime())
                .setDbIds(ListUtil.toList("90001"))
                .setImage(formatBase64ToImage(portraitRequest.getPhotoBase64()));
        AisPortraitsAddResponse response = portraitsService1.portraitsAdd(aisPortraitsAddRequest);
        return response;
    }

    public static String formatBase64ToImage(String base64Image){
        if(!StrUtil.startWith(base64Image,"data:image")){
            return "data:image/jpg;base64,"+base64Image;
        }else{
            return base64Image;
        }
    }

    public void distinctHandler(AisEventReceiver receiver){
        long capTime = receiver.getCapturedTime();
        String identity = receiver.getParticular().getPortrait().getIdentity();
        if(timedCache.containsKey(identity)){
            long time = timedCache.get(identity);
            if(capTime-time<1000*60*1){
                return;
            }
        }
        save2DB(receiver);
    }


    public void testInsert(){
        XCCJZP xccjzp = new XCCJZP();
        xccjzp.setRYBH("52222119940604241X");
        xccjzp.setXSD("82.39583");
        xccjzp.setSBBH("09067004311310266025");
        xccjzp.setCJSJ(DateUtil.format(new Date(),"yyyyMMddHHmmss"));
        xccjzp.setZPZP(ResourceUtil.readBytes("1745131849549.png"));
        xccjzpMapper.insert(xccjzp);
    }

    public void testSelect(){
        XCCJZP zpid = xccjzpMapper.selectOne(new QueryWrapper<XCCJZP>().eq("ZPID", "20250424145158004021"));
        if(zpid!=null){
            log.info(StrUtil.format("{},{},{},{}",zpid.getCJSJ(),zpid.getRYBH(),zpid.getWZXX(),zpid.getXSD()));
            if(zpid.getRLZP()!=null){
                FileUtil.writeBytes(zpid.getRLZP(),"d:/ss/"+System.currentTimeMillis()+".png");
            }
        }
    }

    public void testFaceLibSearch(){
        byte[] zp = ResourceUtil.readBytes("1745131849549.png");
        String encode = Base64.encode(zp);
        faceApiService.faceLibSearch(encode);
    }

    public void execute(){
        xccjzpMapper.callDJJK();
    }

    public void boxHandler(String eventStr){
        wdboxService.eventHandler(eventStr);
    }

}
